// SPDX-License-Identifier: GPL-2.0
/*
 * Early serial console for Lombo uart
 *
 * Copyright (C) 2016-2018, LomboTech Co.Ltd.
 * Author: lomboswer <lomboswer@lombotech.com>
 *
 * This is for use before the serial driver has initialized, in
 * particular, before the UARTs have been discovered and named.
 * Instead of specifying the console device as, e.g., "ttyS0",
 * we locate the device directly by its MMIO or I/O port address.
 *
 * The user can specify the device directly, e.g.,
 *	earlycon=early_lombo,mmio32,0x04003000,115200n8
 */

#include <linux/console.h>
#include <linux/serial_core.h>
#include <linux/io.h>
#include "lombo_uart.h"

static void early_lombo_uart_putc(struct uart_port *port, int c)
{
	/* wait tx fifo not full */
	while (!csp_uart_tx_fifo_not_full(port->membase))
		;

	/* xfer one character */
	csp_uart_putchar(port->membase, c);
}

static void early_lombo_uart_write(struct console *console,
					const char *s, unsigned int count)
{
	struct earlycon_device *device = console->data;
	struct uart_port *port = &device->port;

	uart_console_write(port, s, count, early_lombo_uart_putc);

	/* wait previous tx fifo empty */
	while (csp_uart_tx_empty(port->membase) == 0)
		;
}

static int __init early_lombo_uart_setup(struct earlycon_device *device,
				       const char *options)
{
	if (!(device->port.membase || device->port.iobase))
		return -ENODEV;

	device->con->write = early_lombo_uart_write;

	return 0;
}

OF_EARLYCON_DECLARE(early_lombo, "early-lombo-uart", early_lombo_uart_setup);
